"""
目录管理增强模块
通过缓存管理、线程池和事务日志等优化机制，确保在资源受限和异常情况下仍能稳定运行。
"""
#include <dokan.h>
#include <windows.h>
#include <iostream>
#include <map>
#include <mutex>
#include <thread>
#include <queue>
#include <list>
#include <algorithm>

// 目录缓存管理类
class DirectoryCacheManager {
public:
    DirectoryCacheManager(size_t maxSize) : maxSize_(maxSize) {}

    void AddToCache(const std::wstring& dir, const std::vector<std::wstring>& files) {
        std::lock_guard<std::mutex> lock(mutex_);
        cache_[dir] = files;
        usageList_.push_back(dir);
        EnsureMaxSize();
    }

    void GetFromCache(const std::wstring& dir, std::vector<std::wstring>& files) {
        std::lock_guard<std::mutex> lock(mutex_);
        auto it = cache_.find(dir);
        if (it != cache_.end()) {
            files = it->second;
            usageList_.erase(std::remove(usageList_.begin(), usageList_.end(), dir), usageList_.end());
            usageList_.push_back(dir);
        }
    }

private:
    void EnsureMaxSize() {
        while (cache_.size() > maxSize_) {
            if (!usageList_.empty()) {
                std::wstring leastUsed = usageList_.front();
                cache_.erase(leastUsed);
                usageList_.pop_front();
            }
        }
    }

    std::map<std::wstring, std::vector<std::wstring>> cache_;
    std::list<std::wstring> usageList_;
    size_t maxSize_;
    std::mutex mutex_;
};

// 线程池类
class ThreadPool {
public:
    ThreadPool(size_t threads) : stop_(false) {
        for (size_t i = 0; i < threads; ++i) {
            workers_.emplace_back([this] {
                while (true) {
                    std::function<void()> task;
                    {
                        std::unique_lock<std::mutex> lock(queueMutex_);
                        condition_.wait(lock, [this] { return stop_ || !tasks_.empty(); });
                        if (stop_ && tasks_.empty()) return;
                        task = std::move(tasks_.front());
                        tasks_.pop();
                    }
                    task();
                }
            });
        }
    }

    template<class F, class... Args>
    void Enqueue(F&& f, Args&&... args) {
        {
            std::unique_lock<std::mutex> lock(queueMutex_);
            if (stop_) throw std::runtime_error("Enqueued after stopping.");
            tasks_.emplace(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
        }
        condition_.notify_one();
    }

    ~ThreadPool() {
        {
            std::unique_lock<std::mutex> lock(queueMutex_);
            stop_ = true;
        }
        condition_.notify_all();
        for (std::thread& worker : workers_) worker.join();
    }

private:
    std::vector<std::thread> workers_;
    std::queue<std::function<void()>> tasks_;
    std::mutex queueMutex_;
    std::condition_variable condition_;
    bool stop_;
};

// 事务日志类
class TransactionLog {
public:
    void LogOperation(const std::wstring& dir, const std::vector<std::wstring>& files) {
        std::lock_guard<std::mutex> lock(mutex_);
        log_.push_back(std::make_pair(dir, files));
    }

    void RecoverFromLog() {
        std::wcout << L"Recovering from transaction log..." << std::endl;
        for (const auto& entry : log_) {
            SyncToDisk(entry.first, entry.second);
        }
    }

private:
    void SyncToDisk(const std::wstring& dir, const std::vector<std::wstring>& files) {
        std::wcout << L"Syncing directory " << dir << L" with " << files.size() << L" files." << std::endl;
    }

    std::vector<std::pair<std::wstring, std::vector<std::wstring>>> log_;
    std::mutex mutex_;
};

// 全局对象
DirectoryCacheManager directoryCacheManager(1024 * 1024 * 1024); // 1GB缓存
ThreadPool threadPool(4); // 4个线程
TransactionLog transactionLog;

// 目录操作回调函数

NTSTATUS FindFiles(
    LPCWSTR FileName,
    PFillFindData FillFindData,
    PDOKAN_FILE_INFO FileInfo
) {
    std::wstring fullPath = GetFullPath(FileName);

    std::vector<std::wstring> cachedFiles;
    directoryCacheManager.GetFromCache(fullPath, cachedFiles);

    if (!cachedFiles.empty()) {
        for (const auto& file : cachedFiles) {
            WIN32_FIND_DATA findData;
            if (GetFileAttributesEx(file.c_str(),